package de.tabuma.formcreator.xml.logik;

import de.tabuma.formcreator.entity.*;
import de.tabuma.soap.entity.*;
import de.tabuma.soap.entity.wsdl.*;
import de.tabuma.soap.entity.soap.*;
import de.tabuma.soap.logik.*;

import java.io.*;
import java.util.logging.*;
import java.net.*;

/**
 * @author $Author: $
 * @version $Revision: $
 * @since $Date: $
 */
public class XmlFacade {
    private static final Logger log = Logger.getLogger(XmlFacade.class.getName());

    public static FormStructur fromXmlToFormStructur(String xml) {
        SoapHandler sh = new SoapHandler(xml);
        FormStructur fs = sh.toFormStructur();
        return fs;
    }
    
    public static String fromFormStructurToXml(FormStructur fs) {
        String xml = "";
        if(!fs.isSequenceOrChoiceOrAll()) {
            xml += "<"+fs.getXMLName()+">";
        }
        for(int i=0;i<fs.getFormStructur().size();i++) {
            FormStructur fStructur = fs.getFormStructur().get(i);
            if(fStructur.getFormStructur().size()==0) {
                xml += "<"+fStructur.getXMLName()+">"+fStructur.getValue()+"</"+fStructur.getXMLName()+">";
            }
            else {
                xml += fromFormStructurToXml(fStructur);
            }
        }
        if(!fs.isSequenceOrChoiceOrAll()) {
            xml += "</"+fs.getXMLName()+">";
        }
        return xml;
    }
    
    public static String getSoapAction(TDefinitions wsdl, String message) {
        String str = "";
        for(int i=0;i<wsdl.getAnyTopLevelOptionalElement().size();i++) {
            AnyElement any = PMF.get(wsdl.getAnyTopLevelOptionalElement().get(i), new AnyElement());
            Object obj = any.toObject();
            if(obj instanceof TBinding) {
                TBinding binding = (TBinding) obj;
                if(binding.getOperation()!=null) {
                    for(int j=0;j<binding.getOperation().size();j++) {
                        TBindingOperation operation = PMF.get(binding.getOperation().get(j), new TBindingOperation());
                        if(operation.getName().equals(message)) {
                            long id = operation.getTExtensibleDocumentedId();
                            TExtensibleDocumented tExtensibleDocumented = PMF.get(id, new TExtensibleDocumented());
                            if(tExtensibleDocumented.getAny()!=null) {
                                for(int k=0;k<tExtensibleDocumented.getAny().size();k++) {
                                    AnyElement any1 = PMF.get(tExtensibleDocumented.getAny().get(k),new AnyElement());
                                    Object obj2 = any1.toObject();
                                    if(obj2 instanceof SOperation) {
                                        SOperation soperation = (SOperation) obj2;
                                        if(soperation.getSoapAction()!=null) {
                                            return soperation.getSoapAction();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return str;
    }

    public static String getAddress(TDefinitions wsdl, String message) {
        String str = "";
        for(int i=0;i<wsdl.getAnyTopLevelOptionalElement().size();i++) {
            AnyElement any = PMF.get(wsdl.getAnyTopLevelOptionalElement().get(i), new AnyElement());
            Object obj = any.toObject();
            if(obj instanceof TService) {
                TService service = (TService) obj;
                if(service.getPort()!=null) {
                    for(int j=0;j<service.getPort().size();j++) {
                        TPort port = PMF.get(service.getPort().get(j), new TPort());
                        TExtensibleDocumented tExtensibleDocumented = PMF.get(port.getTExtensibleDocumentedId(), new TExtensibleDocumented());
                        if(tExtensibleDocumented!=null) {
                            for(int k=0;k<tExtensibleDocumented.getAny().size();k++) {
                                Long nr1 = tExtensibleDocumented.getAny().get(k);
                                AnyElement any1 = PMF.get(nr1, new AnyElement());
                                Object obj2 = any1.toObject();
                                if(obj2 instanceof SAddress) {
                                    SAddress saddress = (SAddress) obj2;
                                    return saddress.getLocation();
                                }
                            }
                        }
                    }
                }
            }
        }
        return str;
    }
    
    public static String getMessageContent(String xml1) {
        try {
            String xml = "";
            String xmlBeginn = "";
            xmlBeginn += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
            xmlBeginn += "<soapenv:Envelope xsi:schemaLocation=\"http://schemas.xmlsoap.org/soap/envelope/ http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tsms=\"http://xml.netbeans.org/schema/TestSchema\">\n<soapenv:Body>";
            
            String xmlEnd = "</soapenv:Body>\n</soapenv:Envelope>";
            
            xml = xmlBeginn +"\n"+xml1+"\n"+xmlEnd;

            return xml;
        }
        catch(Exception e) {
            log.warning(e.getMessage()+"/"+e.getCause()+"/"+e.getCause());
        }
        return null;
    }

    public static final String iso_8859_1 = "iso-8859-1";
    public static final String iso_8859_15 = "iso-8859-15";
    public static final String utf8 = "utf-8";

    public static String getCharset(String xml) {
        if(xml.indexOf("ä")!=-1) {
            return iso_8859_15;
        }
        if(xml.indexOf("Ä")!=-1) {
            return iso_8859_15;
        }
        if(xml.indexOf("ü")!=-1) {
            return iso_8859_15;
        }
        if(xml.indexOf("Ü")!=-1) {
            return iso_8859_15;
        }
        if(xml.indexOf("ö")!=-1) {
            return iso_8859_15;
        }
        if(xml.indexOf("Ö")!=-1) {
            return iso_8859_15;
        }
        if(xml.indexOf("ß")!=-1) {
            return iso_8859_15;
        }
        if(xml.indexOf("€")!=-1) {
            return iso_8859_1;
        }
        return utf8;
    }

    public static String doRequest(TDefinitions wsdl, String method , String xml1) {

        String xml = getMessageContent(xml1);
        String soapAction = getSoapAction(wsdl, method);
        String url = getAddress(wsdl, method);
        String charset = getCharset(xml);
        try {
            URL wsdlUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) wsdlUrl.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            conn.setDoInput (true);
            conn.setDoOutput (true);
            conn.setUseCaches (false);
            conn.setAllowUserInteraction(true);
            conn.setInstanceFollowRedirects(false);
            conn.setRequestProperty ("Content-Type","text/xml; charset="+charset);
            conn.setRequestProperty("SoapAction", "\""+soapAction+"\"");
            
            log.warning("sending:\n"+xml);

            PrintStream outStream = new PrintStream(conn.getOutputStream());
            outStream.print(xml);
            outStream.close();

            BufferedReader inStream = new BufferedReader(new InputStreamReader(conn.getInputStream(),utf8));
            
            String response = "";
            String str = "";
            while ((str = inStream.readLine())!=null) {
                response += str;
            }
            inStream.close();
            log.fine("current response:" + response);
            
            
            response = replaceSoapContent(response);
            log.fine("removing soap content:"+response);

            return response;
        }
        catch(Exception e) {
            log.warning(e.getMessage()+"/"+e.getCause()+"/"+e.getClass());
            String warning = "";
            for(int i=0;i<e.getStackTrace().length;i++) {
                warning += e.getStackTrace()[i] + "\n";
            }
            log.warning(warning);
        }
        return xml;

    }

    /**
     *
     * @param xml
     * @param tns Targetnamespace
     * @return
     */
    public static String replaceSoapContent(String xml) {
        String string1 = "<SOAP-ENV:Body>";
        String string2 = "</SOAP-ENV:Body>";
        int indexOf1 = xml.indexOf(string1);
        int indexOf2 = xml.lastIndexOf(string2);
        
        xml = xml.substring(indexOf1+string1.length(),indexOf2);
        FormStructur fs = fromXmlToFormStructur(xml);

        xml = fromFormStructurToXml(fs);

        return xml;
    }
}